import { ChangeDetectorRef, Component, OnInit, ViewChild } from '@angular/core';
import { NzMessageService } from 'ng-zorro-antd/message';
import { ColumnDrawerComponent } from './column-drawer/column-drawer.component';
import { DeleteColumnComponent } from './delete-column/delete-column.component';
import { DeleteDataComponent } from './delete-data/delete-data.component';
import { HttpService } from './http.service';
import { SetNameComponent } from './set-name/set-name.component';
import { XlsxService } from '@delon/abc/xlsx';
import { NzUploadFile } from 'ng-zorro-antd/upload';
import { DatePipe } from '@angular/common';

@Component({
  selector: 'app-excel',
  templateUrl: './excel.component.html',
  styleUrls: ['./excel.component.css'],
  providers: [DatePipe],
})
export class ExcelComponent implements OnInit {
  editCache: { [key: string]: { edit: boolean; data: any } } = {};
  listOfData: any[] = [];
  listOfColumn: any = [];
  title = '<未命名表格>';

  @ViewChild('columnDrawer') columnDrawer!: ColumnDrawerComponent;
  @ViewChild('deleteColumn') deleteColumn!: DeleteColumnComponent;
  @ViewChild('deleteData') deleteData!: DeleteDataComponent;
  @ViewChild('setName') setName!: SetNameComponent;

  startEdit(id: string): void {
    this.editCache[id].edit = true;
  }
  saveEdit(id: string): void {
    const index = this.listOfData.findIndex((item) => item.id === id);
    Object.assign(this.listOfData[index], this.editCache[id].data);
    this.editCache[id].edit = false;
  }

  async updateEditCache(): Promise<void> {
    this.listOfData.forEach((item) => {
      this.editCache[item.id] = {
        edit: false,
        data: { ...item },
      };
    });
  }
  constructor(
    private http: HttpService,
    private message: NzMessageService,
    private xlsx: XlsxService,
    private cdr: ChangeDetectorRef,
    private datePipe: DatePipe
  ) {}

  ngOnInit(): void {
    // const data: any = [];
    // for (let i = 0; i < 100; i++) {
    //   data.push({
    //     id: `${i}`,
    //     name: `Edrward ${i}`,
    //     age: "32",
    //     address: `London Park no. ${i}`,
    //   });
    // }

    // this.listOfColumn = [
    //   { field: 'name', type: 'text' },
    //   { field: 'age', type: 'number' },
    //   { field: 'address', type: 'text' },
    // ];
    // this.listOfData = data;
    this.updateEditCache();
  }
  isNull(data: any) {
    return data == undefined || data == null ? '' : data;
  }
  onSaveTable() {
    if (this.title != '' && this.title != '<未命名表格>') {
      if (this.listOfData.length) {
        let key3 = this.listOfData.map((i) => {
          let item = this.listOfColumn.map(
            (j: { type: string; field: string | number }) => {
              if (j.type == 'date') {
                return this.isNull(
                  this.datePipe.transform(i[j.field], 'yyyy-MM-dd')
                );
              } else {
                return this.isNull(i[j.field]);
              }
            }
          );
          return { values: item };
        });

        this.http
          .post('save_table', {
            name: this.title,
            key: this.listOfColumn,
            value: key3,
          })
          .subscribe(
            (res) => {
              console.log(res);
            },
            (e) => {
              this.message.error('发生错误，错误信息：' + e.statusText);
            }
          );
      } else {
        this.message.error('表格数据为空');
      }
    } else {
      this.message.error('未设置表名');
      this.setName.open();
    }
  }

  onCreateColumn() {
    this.columnDrawer.open();
  }

  onDeleteColumn() {
    this.deleteColumn.open();
  }
  onChangeName() {
    this.setName.open();
  }
  onDeleteData() {
    this.deleteData.open();
  }
  onAddData() {
    if (!this.listOfColumn.length) {
      this.message.error('未设置列名');
      return;
    }
    let item: any = {};
    if (!this.listOfData.length) {
      item.id = 0;
    } else {
      item.id = Number(this.listOfData[this.listOfData.length - 1].id) + 1;
    }
    this.listOfColumn.map((i: { field: string | number }) => {
      item[i.field] = '';
    });
    this.listOfData.push(item);
    this.updateEditCache();
  }

  setColumn(res: any) {
    res.column.map((i: any) => {
      this.listOfColumn.push(i);
      this.listOfData.forEach((data) => {
        if (res.shouldClear) {
          data[i.field] = '';
        }
      });
    });
    if(this.excelData){
      this.listOfData = this.excelData;
      this.excelData = [];
    }
    this.updateEditCache();
  }

  setDeleteColumn(res: string[]) {
    let temp = res;
    for (let i = 0; i < this.listOfColumn.length; i++) {
      if (temp.length && this.listOfColumn[i].name == temp[0]) {
        this.listOfColumn.splice(i, 1);
        this.listOfData.forEach((data) => {
          delete data[temp[0]];
        });
        temp.splice(0, 1);
        i--;
      }
    }

    this.updateEditCache();
  }

  setDeleteData(res: any) {
    if (Object.keys(res).length) {
      this.listOfData.splice(
        Number(res.first) - 1,
        Number(res.second) - Number(res.first) + 1
      );
    } else {
      this.listOfData.splice(Number(res) - 1, 1);
    }
    this.updateEditCache();
  }

  onSetName(res: string) {
    this.title = res;
  }

  beforeUpload = (file: NzUploadFile): boolean => {
    this.getExcelData(file);
    return false;
  };

  excelData: any;
  fileList: any;
  importColumn: any;
  count = 0;

  isExcel(fileName: string): boolean {
    let excelist = ['xls', 'xlsx'];
    // 后缀获取
    var suffix = '';

    let result = false;
    // 获取类型结果
    try {
      var flieArr = fileName.split('.');
      suffix = flieArr[flieArr.length - 1];
    } catch (err) {
      suffix = '';
    }
    // file无后缀返回 false
    if (!suffix) {
      return result;
    }
    result = excelist.some(function (item) {
      return item == suffix;
    });
    return result;
  }

  // 获取Excel内容
  async getExcelData(file: NzUploadFile) {
    if (!this.isExcel(file.name)) {
      this.message.error('仅支持表格文件');
      return;
    }
    let data: any[] = [];
    await this.xlsx.import(file as unknown as File).then((res) => {
      data.push(res);
      this.cdr.detectChanges();
    });

    // 获取表格名称
    const props = Object.keys(data.reduce((o, c) => ({ ...o, ...c })))[0];

    this.count = 0;
    // 由['a','b','c'],[1,2,3],[4,5,6] => [{'a':1, 'b':2, 'c':3},{'a':4, 'b':5, 'c':6}]
    this.excelData = data[0][props].slice(1).map((vals: any[]) => {
      const obj: any = {};
      vals.forEach((val, index) => {
        let item = data[0][props][0][index];
        obj[item] = val;
      });
      obj.id = this.count;
      this.count++;
      return obj;
    });
    this.importColumn = data[0][props][0];
    this.columnDrawer.import(this.importColumn);
  }

  onExportExcel() {
    if (this.title == '' || this.title == '<未命名表格>') {
      this.message.error('未设置表名');
      this.setName.open();
      return;
    }
    const data = [this.listOfColumn.map((i: { field: any }) => i.field)];
    this.listOfData.map((i) => {
      let item = this.listOfColumn.map((j: { field: string | number }) => {
        return i[j.field];
      });
      data.push(item);
    });
    this.xlsx.export({
      filename: this.title + '.xlsx',
      sheets: [
        {
          data,
          name: this.title,
        },
      ],
    });
  }
}
